#include "BlockQueue.hpp"
#include "Task.hpp"
#include <sys/types.h>
#include <unistd.h>
#include <string>
#include <ctime>

template<class C,class S>
class BlockQueues
{
public:
    BlockQueue<C> *c_bq;
    BlockQueue<S> *s_bq;
};

int mymath(int x, int y, char op);

void *consumer(void *_bq)
{
    BlockQueue<CalTask> *bq = (static_cast<BlockQueues<CalTask,SaveTask> *>(_bq)->c_bq);
    BlockQueue<SaveTask> *save_bq = (static_cast<BlockQueues<CalTask,SaveTask> *>(_bq)->s_bq);

    while (true)
    {
        // 在这里消费
        CalTask t;
        bq->pop(&t);
        std::string result = t();
        std::cout << "消费数据: " << t() << std::endl;

        // SaveTask save(result,Save);

        // save_bq->push(save);

        // std::cout<<"推送任务完成..."<<std::endl;

        // sleep(1);//验证符合不
    }

    return nullptr;
}

void *productor(void *_bq)
{
    BlockQueue<CalTask> *bq = (static_cast<BlockQueues<CalTask,SaveTask> *>(_bq)->c_bq);

    while (true)
    {
        // 在这里生产
        int x = rand() % 10 + 1; // 在这里先用随机数构造一个数据
        int y = rand() % 5;  // 在这里先用随机数构造一个数据

        int operCode = rand()%oper.size();

        CalTask t(x, y,oper[operCode] ,mymath);

        bq->push(t);
        std::cout << "生产数据: " << t.toTeskString() << std::endl;
        sleep(1);
    }

    return nullptr;
}


void* saver(void* _bq)
{
    BlockQueue<SaveTask> *save_bq = (static_cast<BlockQueues<CalTask,SaveTask> *>(_bq)->s_bq);
    while(1)
    {
        SaveTask t;
        save_bq->pop(&t);
        t();
        std::cout<<"保存任务完成..."<<std::endl;
    }
    return nullptr;
}

int main()
{
    srand((unsigned long)time(nullptr) ^ getpid());

    BlockQueues<CalTask,SaveTask> bqs;

    bqs.c_bq = new BlockQueue<CalTask>(); // 这是一个临界资源，
    bqs.s_bq = new BlockQueue<SaveTask>(); // 这是用于存储，

    pthread_t c[2], p[3], s;

    pthread_create(c, nullptr, consumer, &bqs);
    pthread_create(c+1, nullptr, consumer, &bqs);
    pthread_create(p, nullptr, productor,&bqs);
    pthread_create(p+1, nullptr, productor,&bqs);
    pthread_create(p+2, nullptr, productor,&bqs);
    //pthread_create(&s,nullptr,saver,&bqs);

    pthread_join(c[0], nullptr); // 线程等待
    pthread_join(c[1], nullptr); // 线程等待
    pthread_join(p[0], nullptr);
    pthread_join(p[1], nullptr);
    pthread_join(p[2], nullptr);
    //pthread_join(s, nullptr);

    delete bqs.c_bq;
    delete bqs.s_bq;
    return 0;
}
